/*
 *  Copyright (c) 2011 Leibniz Institute of Plant Genetics and Crop Plant Research (IPK), Gatersleben, Germany.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the GNU Lesser Public License v2.1
 *  which accompanies this distribution, and is available at
 *  http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 *
 *  Contributors:
 *      Leibniz Institute of Plant Genetics and Crop Plant Research (IPK), Gatersleben, Germany - RMI Server and wrapper
 */
package de.ipk_gatersleben.bit.bi.edal.rmi.server.wrapper;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.security.Principal;
import java.util.List;
import java.util.Map;

import javax.security.auth.Subject;

import de.ipk_gatersleben.bit.bi.edal.aspectj.security.GrantableMethods.Methods;
import de.ipk_gatersleben.bit.bi.edal.primary_data.DataManager;
import de.ipk_gatersleben.bit.bi.edal.primary_data.file.ImplementationProvider;
import de.ipk_gatersleben.bit.bi.edal.primary_data.file.PrimaryDataDirectoryException;
import de.ipk_gatersleben.bit.bi.edal.primary_data.file.EdalException;
import de.ipk_gatersleben.bit.bi.edal.primary_data.metadata.MetaData;
import de.ipk_gatersleben.bit.bi.edal.primary_data.security.EdalAuthenticateException;
import de.ipk_gatersleben.bit.bi.edal.rmi.interfaces.DataManagerRmiInterface;
import de.ipk_gatersleben.bit.bi.edal.rmi.interfaces.PrimaryDataDirectoryRmiInterface;
import de.ipk_gatersleben.bit.bi.edal.rmi.server.Authentication;

/**
 * Wrapper class to wrap {@link DataManager} functions on server side.
 * 
 * @author arendd
 */
public class DataManagerWrapper extends UnicastRemoteObject implements
		DataManagerRmiInterface {

	private static final long serialVersionUID = 1L;

	private ImplementationProvider implementationProvider;

	private int dataPort;

	/**
	 * @return the dataPort
	 */
	private int getDataPort() {
		return dataPort;
	}

	/**
	 * @param dataPort
	 *            the dataPort to set
	 */
	private void setDataPort(int dataPort) {
		this.dataPort = dataPort;
	}

	/**
	 * Constructor for {@link DataManagerWrapper}.
	 * 
	 * @throws RemoteException
	 *             if unable to call remote function.
	 */
	public DataManagerWrapper() throws RemoteException {
		super();
	}

	/**
	 * Constructor for DataManagerWrapper.
	 * 
	 * @param dataPort
	 *            the data port.
	 * 
	 * @param implementationProvider
	 *            a {@link ImplementationProvider} object.
	 * @throws RemoteException
	 *             if unable to call remote function.
	 */
	public DataManagerWrapper(
			final ImplementationProvider implementationProvider, int dataPort)
			throws RemoteException {
		super(dataPort);
		this.implementationProvider = implementationProvider;
		this.setDataPort(dataPort);

	}

	/** {@inheritDoc} */
	@Override
	public PrimaryDataDirectoryRmiInterface getRootDirectory(
			final Subject subject) throws RemoteException,
			PrimaryDataDirectoryException {

		return (PrimaryDataDirectoryRmiInterface) new PrimaryDataDirectoryWrapper(
				this.getDataPort(), DataManager.getRootDirectory(
						this.implementationProvider, subject));

	}

	/** {@inheritDoc} */
	@Override
	public MetaData createMetaDataInstance() throws RemoteException {
		return this.implementationProvider.createMetaDataInstance();
	}

	/** {@inheritDoc} */
	@Override
	public void shutdown() throws RemoteException {
		this.implementationProvider.shutdown();
	}

	/** {@inheritDoc} */
	@Override
	public Map<Principal, List<Methods>> getDefaultPermissions()
			throws RemoteException {
		return DataManager.getDefaultPermissions();
	}

	/** {@inheritDoc} */
	@Override
	public Long getAvailableStorageSpace() throws RemoteException,
			EdalException {
		return DataManager.getAvailableStorageSpace();
	}

	/** {@inheritDoc} */
	@Override
	public Long getUsedStorageSpace() throws RemoteException, EdalException {
		return DataManager.getUsedStorageSpace();
	}

	/** {@inheritDoc} */
	@Override
	public List<Class<? extends Principal>> getSupportedPrincipals()
			throws RemoteException, EdalException {
		return DataManager.getSupportedPrincipals();
	}

	@Override
	public Subject authenticate(Authentication authentication)
			throws RemoteException, EdalAuthenticateException {

		return authentication.getSubject();

	}

}